/*
package org.example.util;


import org.example.bean.Cord;
import org.example.GridMapDrawing;
import org.example.bean.JsonGamePos;
import org.example.bean.Node;

import javax.swing.*;
import java.util.*;

*/
/**
 * @Desc:
 * @Author: yanghongjun
 * @Date: 2024/5/10
 **//*

public class AStarUtil {

    public final static int DIRECT_VALUE = 10; // 横竖移动代价
    public final static int OBLIQUE_VALUE = 14; // 斜移动代价


    */
/**
     * 开始算法，循环移动结点寻找路径
     *//*

    public static List<JsonGamePos> findRoads(int[][] maps, Node start, Node end) {
        List<JsonGamePos> roads = new ArrayList<>();
        if (start == null || !isValidNode(maps, start) || !isValidNode(maps, end)) {
            return roads;
        }

        long now = System.currentTimeMillis();
        PriorityQueue<Node> openList = new PriorityQueue<>(Comparator.comparingInt(Node::getH));
        HashSet<Cord> closeList = new HashSet<>();
        Map<Cord, Node> openNodeMap = new HashMap<>();

        openList.add(start);
        openNodeMap.put(start.getCord(), start);
        System.out.println("开始寻路");
        moveNodes(maps, openList, openNodeMap, closeList, end);

        int time = (int) (System.currentTimeMillis() - now);
        System.out.println("寻路耗时：" + time + " 毫秒");
        // 路径平滑处理（可选）
        List<Cord> path = reconstructPath(end);
        path = smoothPath(path);
        // 直观测试绘制路径
        String name = "寻路耗时" + time + "毫秒,寻路代价：" + end.getG();
        List<Cord> finalPath = path;
        SwingUtilities.invokeLater(() -> {
            GridMapDrawing gameDraw = new GridMapDrawing(maps, finalPath, name);
            gameDraw.setVisible(true);
        });
        // 将路径转换为JsonGamePos列表（如果需要）
        for (Cord cord : path) {
            roads.add(new JsonGamePos(cord.x, cord.y));
        }

        return roads;
    }

    */
/**
     * 节点是否有效
     *
     * @param maps
     * @param node
     * @return
     *//*

    private static boolean isValidNode(int[][] maps, Node node) {
        return node != null && node.getCord() != null &&
                node.getCord().x >= 0 && node.getCord().x < maps.length &&
                node.getCord().y >= 0 && node.getCord().y < maps[0].length &&
                maps[node.getCord().x][node.getCord().y] != 1;
    }

    */
/**
     * 移动当前结点并添加邻居节点
     *//*

    private static void moveNodes(int[][] maps, PriorityQueue<Node> openList, Map<Cord, Node> openNodeMap, HashSet<Cord> closeList, Node end) {
        while (!openList.isEmpty()) {
            Node current = openList.poll();
            closeList.add(current.getCord());
            openNodeMap.remove(current.getCord());
            if (isEndNode(end.getCord(), current.getCord())) {
                break; // 找到目标，提前结束搜索
            }
            addNeighborNodesInOpen(maps, openList, openNodeMap, closeList, end, current);
        }
    }

    */
/**
     * 一次性添加所有邻居节点到Open列表
     *//*

    private static void addNeighborNodesInOpen(int[][] maps, PriorityQueue<Node> openList, Map<Cord, Node> openNodeMap, HashSet<Cord> closeList, Node end, Node current) {
        int x = current.getCord().x;
        int y = current.getCord().y;

        // 定义所有可能的移动方向
        int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {-1, -1}, {1, -1}, {1, 1}, {-1, 1}};
        int[] values = {DIRECT_VALUE, DIRECT_VALUE, DIRECT_VALUE, DIRECT_VALUE, OBLIQUE_VALUE, OBLIQUE_VALUE, OBLIQUE_VALUE, OBLIQUE_VALUE};
        for (int i = 0; i < directions.length; i++) {
            int newX = x + directions[i][0];
            int newY = y + directions[i][1];
            if (isValidCoordinate(maps, newX, newY)) {
                Cord cord = new Cord(newX, newY);
                int G = current.getG() + values[i];
                if (!closeList.contains(cord)) {
                    Node neighbor = findNodeInOpen(cord, openNodeMap);
                    if (neighbor == null) {
                        int H = calcH(end.getCord(), cord);
                        if (isEndNode(end.getCord(), cord)) {
                            neighbor = end;
                            neighbor.setParent(current);
                            neighbor.setG(G);
                            neighbor.setH(H);
                            break;
                        } else {
                            neighbor = new Node(cord, current, G, H);
                        }
                        openList.add(neighbor);
                        openNodeMap.put(cord, neighbor);
                    } else if (neighbor.getG() > G) {
                        neighbor.setG(G);
                        neighbor.setParent(current);
                    }
                }
            }
        }
    }

    */
/**
     * 判断坐标是否在地图范围内且可通过
     *//*

    private static boolean isValidCoordinate(int[][] maps, int x, int y) {
        return x >= 0 && x < maps.length && y >= 0 && y < maps[0].length && maps[x][y] != 1;
    }

    */
/**
     * 路径重构并平滑处理
     *//*

    private static List<Cord> smoothPath(List<Cord> path) {
        if (path.size() < 3) {
            return path; // 路径太短，无需平滑
        }

        List<Cord> smoothedPath = new ArrayList<>();
        smoothedPath.add(path.get(0)); // 起点始终加入平滑路径

        for (int i = 1; i < path.size() - 1; i++) {
            Cord current = path.get(i);
            Cord prev = path.get(i - 1);
            Cord next = path.get(i + 1);

            // 如果当前点和前后点共线，则跳过当前点（简单平滑）
            if (!(prev.x == current.x && next.x == current.x && (prev.y < current.y == next.y < current.y)) &&
                    !(prev.y == current.y && next.y == current.y && (prev.x < current.x == next.x < current.x))) {
                smoothedPath.add(current);
            }
        }

        smoothedPath.add(path.get(path.size() - 1)); // 终点始终加入平滑路径
        return smoothedPath;
    }


    */
/**
     * 判断结点是否是最终结点
     *//*

    private static boolean isEndNode(Cord end, Cord cord) {
        return end.equals(cord);
    }

    */
/**
     * 计算 H 值，“曼哈顿” 法，坐标分别取差值相加
     *
     * @param end
     * @param cord
     * @return
     *//*

    private static int calcH(Cord end, Cord cord) {
        return (Math.abs(end.x - cord.x) + Math.abs(end.y - cord.y)) * DIRECT_VALUE;
    }

    */
/**
     * 在Open列表中查找结点
     *//*

    private static Node findNodeInOpen(Cord cord, Map<Cord, Node> openNodeMap) {
        return openNodeMap.get(cord);
    }


    */
/**
     * 路径重构：从目标节点回溯到起始节点
     *//*

    private static List<Cord> reconstructPath(Node end) {
        List<Cord> path = new ArrayList<>();
        while (end != null) {
            path.add(0, end.getCord()); // 将当前节点添加到路径的开头
            end = end.getParent();
        }
        return path;
    }

    */
/**
     * 判断结点能否放入Open列表
     *//*

    private static boolean canAddNodeToOpen(int x, int y, int[][] maps, HashSet<Cord> closeList) {
        // 是否在地图中
        if (x < 0 || x >= maps.length || y < 0 || y >= maps[0].length) {
            return false;
        }
        // 判断是否是不可通过的结点
        if (maps[x][y] == 1) {
            return false;
        }
        // 判断结点是否存在close表
        if (isCordInClose(new Cord(x, y), closeList)) {
            return false;
        }
        return true;
    }


    */
/**
     * 判断坐标是否在close表中
     *//*

    private static boolean isCordInClose(Cord card, HashSet<Cord> closeList) {
        return card != null && closeList.contains(card);
    }

}
*/
